// HandleFunc registers the handler function for the given pattern. func(mux *ServeMux)HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { if handler == nil { panic("http: nil handler") } // 这里调用了自身的Handle方法, HandlerFunc 函数类型 mux.Handle(pattern, HandlerFunc(handler)) }
// Handle registers the handler for the given pattern. // If a handler already exists for pattern, Handle panics. func(mux *ServeMux)Handle(pattern string, handler Handler) { mux.mu.Lock() defer mux.mu.Unlock()
if pattern == "" { panic("http: invalid pattern") } if handler == nil { panic("http: nil handler") } if _, exist := mux.m[pattern]; exist { panic("http: multiple registrations for " + pattern) }
if !srv.trackListener(&l, true) { return ErrServerClosed } defer srv.trackListener(&l, false)
var tempDelay time.Duration // how long to sleep on accept failure baseCtx := context.Background() // base is always background, per Issue 16220 ctx := context.WithValue(baseCtx, ServerContextKey, srv) for { rw, e := l.Accept() // 阻塞监听客户端的连接 if e != nil { select { case <-srv.getDoneChan(): return ErrServerClosed default: } if ne, ok := e.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay) time.Sleep(tempDelay) continue } return e } tempDelay = 0 // 这里表示,有客户端的请求进来 // 调用Server的newConn方法,获取到一个连接 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // before Serve can return go c.serve(ctx) // 使用goroutines处理我们的请求 } }
// Create new connection from rwc. func(srv *Server)newConn(rwc net.Conn) *conn { c := &conn{ server: srv, // 将Server实例传入,初始化conn rwc: rwc, } if debugServerConnections { c.rwc = newLoggingConn("server", c.rwc) } return c }
// HTTP cannot have multiple simultaneous active requests.[*] // Until the server replies to this request, it can't read another, // so we might as well run the handler in this goroutine. // [*] Not strictly true: HTTP pipelining. We could let them all process // in parallel even if their responses need to be serialized. // But we're not going to implement HTTP pipelining because it // was never deployed in the wild and the answer is HTTP/2. // 内部的serverHandler结构体,获取Server对象,创建 // serverHandler实例,并调用ServerHTTP方法 serverHandler{c.server}.ServeHTTP(w, w.req) ..... }
// serverHandler delegates to either the server's Handler or // DefaultServeMux and also handles "OPTIONS *" requests. type serverHandler struct { srv *Server }
// CONNECT requests are not canonicalized. if r.Method == "CONNECT" { // If r.URL.Path is /tree and its handler is not registered, // the /tree -> /tree/ redirect applies to CONNECT requests // but the path canonicalization does not. if u, ok := mux.redirectToPathSlash(r.URL.Host, r.URL.Path, r.URL); ok { return RedirectHandler(u.String(), StatusMovedPermanently), u.Path }
return mux.handler(r.Host, r.URL.Path) }
// All other requests have any port stripped and path cleaned // before passing to mux.handler. host := stripHostPort(r.Host) path := cleanPath(r.URL.Path)
// If the given path is /tree and its handler is not registered, // redirect for /tree/. if u, ok := mux.redirectToPathSlash(host, path, r.URL); ok { return RedirectHandler(u.String(), StatusMovedPermanently), u.Path }